//
//  HMEmoticonTools.swift
//  Weibo
//
//  Created by itteacher on 2017/8/1.
//  Copyright © 2017年 itteacher. All rights reserved.
//

import UIKit
import YYModel

//  每页显示表情的个数
let NumberOfPage = 20
//  归档和解档的路径
private let RecentEmoticonArrayPath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as NSString).appendingPathComponent("recentEmotionArray.archive")

//  表情工具类，负责读取表情数据和存储等操作
class HMEmoticonTools: NSObject {

    //  单例的全局访问点
    static let sharedTools: HMEmoticonTools = HMEmoticonTools()
    //  构造函数私有化
    private override init() {
        super.init()
    }
    
    //  创建emoticonBundle对象
    lazy var emoticonBundle: Bundle = {
        let path = Bundle.main.path(forResource: "Emoticons.bundle", ofType: nil)!
        //  根据路径创建bundle
        let bundle = Bundle(path: path)!
        return bundle
    }()
    
    //  默认表情
    private lazy var defaultEmoticonArray: [HMEmoticon] = {
        return self.loadEmoticonPlistData(folderName: "default", fileName: "info.plist")
    }()
    
    //  emoji表情
    private lazy var emojiEmoticonArray: [HMEmoticon] = {
        return self.loadEmoticonPlistData(folderName: "emoji", fileName: "info.plist")
    }()
    
    //  浪小花表情
    private lazy var lxhEmoticonArray: [HMEmoticon] = {
        return self.loadEmoticonPlistData(folderName: "lxh", fileName: "info.plist")
    }()
    
    //  最近表情
    private lazy var recentEmoticonArray: [HMEmoticon] = {
        if let localArray = self.loadLocalRecentEmoticonData() {
            return localArray
        }
        //  代码执行到此表示没有最近表情返回空数组
        let array = [HMEmoticon]()
        return array
    }()
    
    //  给表情视图准备所需要数据
    lazy var allEmoticonArray: [[[HMEmoticon]]] = {
        return [
            //  最近表情
            [self.recentEmoticonArray],
            //  默认二维数组
            self.sectionWith(emoticonArray: self.defaultEmoticonArray),
            //  emoji二维数组
            self.sectionWith(emoticonArray: self.emojiEmoticonArray),
            //  浪小花二维数组
            self.sectionWith(emoticonArray: self.lxhEmoticonArray)
        ]
        
    }()
    
    /// 根据每种表情拆分成对应的二维数组
    ///
    /// - Parameter emoticonArray: 每种表情
    /// - Returns:这个中表情对应的二维数组
    private func sectionWith(emoticonArray: [HMEmoticon]) -> [[HMEmoticon]] {
        //  根据表情个数计算显示的页数
        let pageCount = (emoticonArray.count - 1) / NumberOfPage + 1
        var tempArray = [[HMEmoticon]]()
        //  遍历页数截取每页对于的表情数据
        for pageIndex in 0..<pageCount {
            //  开始截取的索引
            let loc = pageIndex * NumberOfPage
            //  截取的长度
            var len = NumberOfPage
            
            if loc + len > emoticonArray.count {
                //  数组越界，截取剩余表情个数
                len = emoticonArray.count - loc
            }
            
            let range = NSMakeRange(loc, len)
            //  截取指定范围的表情数据
            let subArray = (emoticonArray as NSArray).subarray(with: range) as! [HMEmoticon]
            tempArray.append(subArray)
            
        }
        return tempArray
        
    }
    
    
    /// 读取表情的通用方法
    ///
    /// - Parameters:
    ///   - folderName: 文件夹名字
    ///   - fileName: 文件名字
    /// - Returns: 模型数组
    private func loadEmoticonPlistData(folderName: String, fileName: String) ->  [HMEmoticon] {
        //  contents和resources这两个文件夹使用path(forResource: 会直接拼接，不需要在指定了
        //  contents resources 这个两个文件夹在创建bundle时候系统会自动生成
        //  子路径
        let subPath = folderName + "/" + fileName
        let path = self.emoticonBundle.path(forResource: subPath, ofType: nil)!
        print(path)
        
        //  根据路径加载plist数据
        let dicArray = NSArray(contentsOfFile: path)!
        //  使用YYModel完成字典转模型
        let modelArray = NSArray.yy_modelArray(with: HMEmoticon.self, json: dicArray) as! [HMEmoticon]
        
        //  遍历表情数组判断是否是图片表情，如果是图片表情设置图片的路径（图片所在文件夹及图片）
        for model in modelArray {
            if model.type == "0" {
                //  图片表情
                let path = folderName + "/" + model.png!
                //  记录图片路径
                model.path = path
            }
        }
        
        
        return modelArray
    }
    
    //  保存最近表情数据
    func saveRecentEmoticonArray(emoticon: HMEmoticon, callBack: ()->()) {
        //  1. 判断最近表情里面是否有该表情
        for (i, recentEmoticon) in recentEmoticonArray.enumerated() {
            if emoticon.type == "0" {
                //  图片表情， 比较表情描述
                if recentEmoticon.chs == emoticon.chs {
                    //  2. 如果有从最近表情里面删除
                    recentEmoticonArray.remove(at: i)
                    break
                }
            } else {
                //  emoji表情， 比较表情code
                if recentEmoticon.code == emoticon.code {
                    //  2. 如果有从最近表情里面删除
                    recentEmoticonArray.remove(at: i)
                    break
                }
            }
        
        }
        
        //  3. 把点击的表情添加到最近表情的最前面
        recentEmoticonArray.insert(emoticon, at: 0)
        //  4. 如果最近表情超过20个从后往前删除最近表情里面的数据
        if recentEmoticonArray.count > 20 {
            //  删除最后一个
            recentEmoticonArray.removeLast()
        }
        //  5. 修改最近表情这个数据源
        allEmoticonArray[0][0] = recentEmoticonArray
       
        //  6. 归档最近表情
        let result = NSKeyedArchiver.archiveRootObject(recentEmoticonArray, toFile: RecentEmoticonArrayPath)
        //  7. 重新加载
        if result {
            callBack()
        }
        
    }
    
    //  加载本地最近表情数据
    private func loadLocalRecentEmoticonData() -> [HMEmoticon]? {
        let localArray = NSKeyedUnarchiver.unarchiveObject(withFile: RecentEmoticonArrayPath) as? [HMEmoticon]
        return localArray
    }
    
    //  根据表情描述查找表情模型
    func selectEmoticonWith(chs: String) -> HMEmoticon? {
        /// 只查找图片表情，默认表情和浪小花表情
        for model in defaultEmoticonArray {
            if model.chs == chs {
                return model
            }
        }
        
        for model in lxhEmoticonArray {
            if model.chs == chs {
                return model
            }
        }
        
        return nil
    }
    
}
